
	.386
if ?FLAT
	.MODEL FLAT, stdcall
else
	.MODEL SMALL, stdcall
endif
	option casemap:none
	option proc:private

	include winbase.inc
	include dkrnl32.inc
	include macros.inc

	.CODE

SetEnvironmentVariableA proc public uses ebx esi edi pName:ptr BYTE, pValue:ptr BYTE

local	dwLength:DWORD
local	dwKeyLen:DWORD
local	dwPSP:DWORD
local	pTmpBlk:DWORD

ifdef _DEBUG
	mov ecx, pValue
	.if (!ecx)
		mov ecx, CStr("NULL")
	.endif
	@strace <"SetEnvironmentVariableA(", &pName, ", ", &ecx, ") enter">
endif

	invoke LocalAlloc, LMEM_FIXED, 8000h
	and eax, eax
	jz exit
	mov edi, eax
	mov pTmpBlk, eax

	mov ah,62h
	int 21h
	mov dwPSP, ebx
	push ds
	mov ds,ebx
	mov bx,ds:[002Ch]
	pop ds

	invoke lstrlen, pName
	mov dwKeyLen, eax

	push ds
	mov ds, ebx
	xor esi, esi
	.while (byte ptr [esi])
		mov ecx, dwKeyLen
		.if (byte ptr [esi+ecx] == '=')
			push esi
			push edi
			mov edi, pName
			repz cmpsb
			pop edi
			pop esi
			.if (ZERO?)
@@:
				lodsb
				and al, al
				jnz @B
				.continue
			.endif
		.endif
@@:
		lodsb
		stosb
		and al, al
		jnz @B
	.endw
	pop ds

	.if (pValue)
		push esi
		mov ecx, dwKeyLen
		mov esi, pName
		rep movsb
		mov al, '='
		stosb
		mov esi, pValue
@@:
		lodsb
		stosb
		and al, al
		jnz @B
		pop esi
	.endif

	push ds
	mov ds, ebx
	movsb
	lodsw
	.if (ax == 1)
		stosw
@@:
		lodsb
		stosb
		and al, al
		jnz @B
	.endif
	pop ds

	sub edi, pTmpBlk 
	mov dwLength, edi
	mov edx, ebx
	mov ebx, edi
	mov cl, bl
	shr ebx, 4
	test cl, 0Fh
	jz @F
	inc ebx
@@:
	mov esi, ebx		;save bx
	mov ax, 0102h		;try to realloc dos memory
	int 31h
	jnc @F
	@strace <"a new DOS memory block for environment must be allocated, ebx=",ebx>
	mov ebx, esi		;failed, now try to alloc new DOS memory
	mov ax, 0100h
	int 31h
	jc error

	push edx
	push ds
	mov ds,dwPSP
	xchg dx, ds:[002Ch]
	pop ds
;;	mov ax, 0101h		;do NOT free old environment block
;;	int 31h
	pop edx

@@:
	push es
	xor edi, edi
	mov es, edx
	mov esi, pTmpBlk
	mov ecx, dwLength
	rep movsb
	pop es
	@mov eax, 1
exit:
	push eax
	invoke LocalFree, pTmpBlk
	pop eax
	@strace <"SetEnvironmentVariableA()=", eax>
	ret
error:
	xor eax, eax
	jmp exit
	align 4
        
SetEnvironmentVariableA endp

SetEnvironmentVariableW proc public pName:ptr WORD, pValue:ptr WORD

	mov eax, pName
	invoke ConvertWStr
	mov pName, eax
	mov eax, pValue
	.if (eax)
		invoke ConvertWStr
	.endif
	invoke SetEnvironmentVariableA, pName, eax
	@strace <"SetEnvironmentVariableW(", pName, ", ", pValue, ")=", eax>
;	xor eax,eax		;v3.10 removed
	ret
	align 4

SetEnvironmentVariableW endp

	end
